package com.threepure.penpipe.util;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.ImageView;

import com.threepure.penpipe.pen.PenConfig;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;

/**
 * @author ThreePure
 * @date 2021/11/17 19:23
 * @description: 图像操作工具类
 * @since 1.8
 */
public class BitmapUtil {

    private static final String TAG = "TP_BitmapUtil=>";
    /**
     * @description:  逐行(像素)扫描 清除边界空白   要求背景色唯一，要是图片那就无法识别
     * @Param: [android.graphics.Bitmap, int blank :边距留多少个像素, int color :背景色限定]
     * @Return: android.graphics.Bitmap  清除边界后的Bitmap
     */
    public static Bitmap clearBlank(Bitmap mBitmap, int blank, int color) {

        if (mBitmap != null) {
            //获得位图的高度和宽度
            int height = mBitmap.getHeight();
            int width = mBitmap.getWidth();
            // 分别记录上下左右最边缘的点的坐标
            int top = 0, left = 0, right = 0, bottom = 0;
            int[] widthPixels = new int[width];
            boolean isStop;
            //找到最上端端的点的位置（y轴上最小值）
            for (int y = 0; y < height; y++) {
                mBitmap.getPixels(widthPixels, 0, width, 0, y, width, 1);
                isStop = false;
                for (int pix : widthPixels) {
                    if (pix != color) {
                        //找到了最上端开始有绘画过程的点，
                        top = y;
                        isStop = true;
                        break;
                    }
                }
                if (isStop) {
                    break;
                }
            }
            //同上找到最下端的点的位置（y轴上最大值）
            for (int y = height - 1; y >= 0; y--) {
                mBitmap.getPixels(widthPixels, 0, width, 0, y, width, 1);
                isStop = false;
                for (int pix : widthPixels) {
                    if (pix != color) {
                        bottom = y;
                        isStop = true;
                        break;
                    }
                }
                if (isStop) {
                    break;
                }
            }
            //同上找到最左端的点的位置（x轴上最小值）
            widthPixels = new int[height];
            for (int x = 0; x < width; x++) {
                mBitmap.getPixels(widthPixels, 0, 1, x, 0, 1, height);
                isStop = false;
                for (int pix : widthPixels) {
                    if (pix != color) {
                        left = x;
                        isStop = true;
                        break;
                    }
                }
                if (isStop) {
                    break;
                }
            }
            //同上找到最左端的点的位置（x轴上最大值）
            for (int x = width - 1; x > 0; x--) {
                mBitmap.getPixels(widthPixels, 0, 1, x, 0, 1, height);
                isStop = false;
                for (int pix : widthPixels) {
                    if (pix != color) {
                        right = x;
                        isStop = true;
                        break;
                    }
                }
                if (isStop) {
                    break;
                }
            }
            //blank是需要留下的边距
            if (blank < 0) {
                blank = 0;
            }
            left = left - blank > 0 ? left - blank : 0;
            top  = top  - blank > 0 ? top  - blank : 0;
            right  = right  + blank > width - 1  ? width  - 1 : right  + blank;
            bottom = bottom + blank > height - 1 ? height - 1 : bottom + blank;
            return Bitmap.createBitmap(mBitmap, left, top, right - left, bottom - top);
        } else {
            return null;
        }
    }

    /**
     * @description:  清除bitmap左右边界空白
     * @Param: [android.graphics.Bitmap mBitmap 源图, int blank边距留多少个像素, int color   背景色限定]
     * @Return: android.graphics.Bitmap  清除后的bitmap
     */
    public static Bitmap clearLRBlank(Bitmap mBitmap, int blank, int color) {
        if (mBitmap != null) {
            int height = mBitmap.getHeight();
            int width = mBitmap.getWidth();
            int left = 0, right = 0;
            int[] pixs = new int[height];
            boolean isStop;
            for (int x = 0; x < width; x++) {
                mBitmap.getPixels(pixs, 0, 1, x, 0, 1, height);
                isStop = false;
                for (int pix : pixs) {
                    if (pix != color) {
                        left = x;
                        isStop = true;
                        break;
                    }
                }
                if (isStop) {
                    break;
                }
            }
            for (int x = width - 1; x > 0; x--) {
                mBitmap.getPixels(pixs, 0, 1, x, 0, 1, height);
                isStop = false;
                for (int pix : pixs) {
                    if (pix != color) {
                        right = x;
                        isStop = true;
                        break;
                    }
                }
                if (isStop) {
                    break;
                }
            }
            if (blank < 0) {
                blank = 0;
            }
            left  = left  - blank > 0 ? left - blank : 0;
            right = right + blank > width - 1 ? width - 1 : right + blank;
            return Bitmap.createBitmap(mBitmap, left, 0, right - left, height);
        } else {
            return null;
        }
    }

    /**给Bitmap添加背景图片*/
    public static Bitmap addBgImage(Bitmap srcBitmap, Bitmap bgBitmap){
        Bitmap bitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
        Canvas canvas = new Canvas(bitmap);

        //将bgBitmap缩放至与手机屏幕相适配
        bgBitmap = zoomImage(bgBitmap, srcBitmap.getWidth(), srcBitmap.getHeight());

        canvas.drawBitmap(bgBitmap, 0 ,0, null);
        canvas.drawBitmap(srcBitmap,0, 0, null);
        return bitmap;

    }

    /**
     * 给Bitmap添加背景色
     * @param srcBitmap 源图
     * @param color     背景颜色
     * @return 修改背景后的bitmap
     */
    public static Bitmap drawBgToBitmap(Bitmap srcBitmap, int color) {
        Paint paint = new Paint();
        paint.setColor(color);

        Bitmap bitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
        Canvas canvas = new Canvas(bitmap);

        canvas.drawRect(0, 0, srcBitmap.getWidth(), srcBitmap.getHeight(), paint);
        canvas.drawBitmap(srcBitmap, 0, 0, paint);
        return bitmap;
    }

    /**
     * @description:  保存图像到本地
     * @Param: [android.content.Context, android.graphics.Bitmap bmp :源图, int quality :压缩质量, java.lang.String format :图片格式]
     * @Return: java.lang.String  返回此文件的绝对路径  或者null
     */
    public static String saveImage(Context context, Bitmap bmp, int quality, String format) {

        if (bmp == null) {
            return null;
        }
        FileOutputStream fos = null;

        try {
            //获得SD卡的根路径
            File sd = Environment.getExternalStorageDirectory();
            //获取SD卡是否能够访问
            boolean can_write = sd.canWrite();

            //返回主共享/外部存储设备上应用程序特定目录的绝对路径，应用程序可以将其拥有的缓存文件放置在该目录中。
            String storePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "APenPipe";
            //文件夹
            File saveDir = new File(storePath);
            if (!saveDir.exists()) {
                saveDir.mkdirs();
            }

            //文件名字，由当前时间戳加上GCZ后缀表示
            String fileName;
            //指定位图可以压缩为的已知格式
            Bitmap.CompressFormat compressFormat;
            if (PenConfig.FORMAT_JPG.equals(format)) {
                compressFormat = Bitmap.CompressFormat.JPEG;
                fileName = System.currentTimeMillis() + "GCZ.jpg";
            } else {
                compressFormat = Bitmap.CompressFormat.PNG;
                fileName = System.currentTimeMillis() + "GCZ.png";
            }

            File file = new File(saveDir, fileName);
            fos = new FileOutputStream(file);
            //如果成功压缩到指定流，则为true
            boolean isSuccess = bmp.compress(compressFormat, quality, fos);
            fos.flush();
            fos.close();

            //保存图片后发送广播通知更新数据库
            Uri uri = Uri.fromFile(file);
            Log.e(TAG, "saveImage: uri: " + uri);
            context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));
            return storePath + "/" + fileName;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;

    }

    /**
     * @description:  根据宽度缩放图片，高度等比例
     * @Param: [android.graphics.Bitmap bm :源图, int newWidth :目标宽度]
     * @Return: android.graphics.Bitmap  缩放后的bitmap
     */
    public static Bitmap zoomImg(Bitmap bm, int newWidth) {

        // 获得图片的宽高
        int width  = bm.getWidth();
        int height = bm.getHeight();
        // 计算缩放比例
        float ratio = ((float) newWidth) / width;
        // 取得想要缩放的matrix参数
        Matrix matrix = new Matrix();
        matrix.postScale(ratio, ratio);
        // 得到新的图片
        return Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);
    }

    /**
     * @description:  缩放图片至指定宽高
     * @Param: [android.graphics.Bitmap bm :源图, int newWidth :新宽度, int newHeight :新高度]
     * @Return: android.graphics.Bitmap  缩放后的bitmap
     */
    public static Bitmap zoomImage(Bitmap bm, int newWidth, int newHeight) {

        // 获得图片的宽高
        int width  = bm.getWidth();
        int height = bm.getHeight();
        // 计算缩放比例
        float scaleWidth  = ((float) newWidth)  / width;
        float scaleHeight = ((float) newHeight) / height;
        // 取得想要缩放的matrix参数
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        // 得到新的图片
        return Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);
    }

    /**
     * @description:  根据宽高之中最大缩放比缩放图片
     * @Param: [android.graphics.Bitmap bitmap :源图,  int newWidth ：新宽度,  int newHeight :目标高度]
     * @Return: android.graphics.Bitmap  缩放后的bitmap
     */
    public static Bitmap zoomImg(Bitmap bitmap, int newWidth,int newHeight) {

        // 获取这个图片的宽和高
        int width  = bitmap.getWidth();
        int height = bitmap.getHeight();
        // 创建操作图片用的matrix对象
        Matrix matrix = new Matrix();
        // 计算宽高缩放率
        float scaleWidth  = ((float) newWidth)  / width;
        float scaleHeight = ((float) newHeight) / height;
        float ratio = Math.max(scaleWidth, scaleHeight);
        // 缩放图片动作
        matrix.postScale(ratio, ratio);
        return Bitmap.createBitmap(bitmap, 0, 0, width,height, matrix, true);
    }

    /**
     * @description:  给图片右下角添加水印
     * @Param: [android.graphics.Bitmap src :源图, android.graphics.Bitmap watermark 水印图, int bgColor :背景色, boolean fixed :源图是否固定大小]
     * @Return: android.graphics.Bitmap  添加水印后的图片
     */
    public static Bitmap addWaterMask(Bitmap src, Bitmap watermark, int bgColor, boolean fixed) {

        int w = src.getWidth();
        int h = src.getHeight();
        //获取原始水印图片的宽、高
        int w2 = watermark.getWidth();
        int h2 = watermark.getHeight();

        //合理控制水印大小
        Matrix matrix1 = new Matrix();
        float ratio;

        ratio = (float) w2 / w;
        if (ratio > 1.0f && ratio <= 2.0f) {
            ratio = 0.7f;
        } else if (ratio > 2.0f) {
            ratio = 0.5f;
        } else if (ratio <= 0.2f) {
            ratio = 2.0f;
        } else if (ratio < 0.3f) {
            ratio = 1.5f;
        } else if (ratio <= 0.4f) {
            ratio = 1.2f;
        } else if (ratio < 1.0f) {
            ratio = 1.0f;
        }
        matrix1.postScale(ratio, ratio);
        watermark = Bitmap.createBitmap(watermark, 0, 0, w2, h2, matrix1, true);

        //获取新的水印图片的宽、高
        w2 = watermark.getWidth();
        h2 = watermark.getHeight();

        if (!fixed) {
            if (w < 1.5 * w2) {
                w = w + w2;
            }
            if (h < 2 * h2) {
                h = h + h2;
            }
        }
        // 创建一个新的和原图长度宽度一样的位图
        Bitmap result = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas cv = new Canvas(result);
        cv.drawColor(bgColor);
        //在canvas上绘制原图和新的水印图
        cv.drawBitmap(src, 0, 0, null);
        //水印图绘制在画布的右下角，距离右边和底部都为20
        cv.drawBitmap(watermark, w - w2 - 20, h - h2 - 20, null);
        cv.save();
        cv.restore();
        return result;
    }

    public static Bitmap addTextWaterMask(Bitmap mBitmap, String text){
        //获取原始图片与水印图片的宽与高
        int mBitmapWidth = mBitmap.getWidth();
        int mBitmapHeight = mBitmap.getHeight();
        Bitmap mNewBitmap = Bitmap.createBitmap(mBitmapWidth, mBitmapHeight, Bitmap.Config.ARGB_8888);
        Canvas mCanvas = new Canvas(mNewBitmap);
        //向位图中开始画入MBitmap原始图片
        mCanvas.drawBitmap(mBitmap,0,0,null);
        //添加文字
        Paint mPaint = new Paint();

        mPaint.setColor(Color.BLACK);
        mPaint.setTextSize(30);
        //水印的位置坐标
        mCanvas.drawText(text, mBitmapWidth -350 ,mBitmapHeight - 30, mPaint);
        mCanvas.save();
        mCanvas.restore();

        return mNewBitmap;
    }

    /**
     * @description:  修改图片颜色
     * @Param: [android.graphics.Bitmap inBitmap :源图, int color :颜色]
     * @Return: android.graphics.Bitmap 修改颜色后的图片
     */
    public static Bitmap changeBitmapColor(Bitmap inBitmap, int color) {

        if (inBitmap == null) {
            return null;
        }
        Bitmap outBitmap = Bitmap.createBitmap(inBitmap.getWidth(), inBitmap.getHeight(), inBitmap.getConfig());
        Canvas canvas = new Canvas(outBitmap);
        Paint  paint  = new Paint();
        //设置或清除油漆的颜色过滤器
        paint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(inBitmap, 0, 0, paint);
        return outBitmap;
    }

    /**
     * @description:  设置ImageView的图片，支持改变图片颜色
     * @Param: [android.widget.ImageView, int, int]
     * @Return: void
     */
    public static void setImage(ImageView iv, int id, int color) {
        Bitmap bitmap = BitmapFactory.decodeResource(iv.getResources(), id);
        iv.setImageBitmap(BitmapUtil.changeBitmapColor(bitmap, color));
    }
}
